var bigqueryAccessRoleToPrimitiveMap =  map[string]string {
    "roles/bigquery.dataOwner": "OWNER",
    "roles/bigquery.dataEditor": "WRITER",
    "roles/bigquery.dataViewer": "READER",
}

func resourceBigQueryDatasetAccessRoleDiffSuppress(k, old, new string, d *schema.ResourceData) bool {
    if primitiveRole, ok := bigqueryAccessRoleToPrimitiveMap[new]; ok {
        return primitiveRole == old
    }
    return false
}

// we want to diff suppress any iam_members that are configured as `iam_member`, but stored in state as a different member type
func resourceBigQueryDatasetAccessIamMemberDiffSuppress(k, old, new string, d *schema.ResourceData) bool {
	if primitiveRole, ok := bigqueryAccessRoleToPrimitiveMap[new]; ok {
		return primitiveRole == old
	}

	if d.Get("api_updated_member") == true {
		expectedIamMember := d.Get("iam_member").(string)
		parts := strings.SplitAfter(expectedIamMember, ":")

		strippedIamMember := parts[0]
		if len(parts) > 1 {
			strippedIamMember = parts[1]
		}

		if memberInState := d.Get("user_by_email").(string); memberInState != "" {
			return memberInState == strippedIamMember
		}

		if memberInState := d.Get("group_by_email").(string); memberInState != "" {
			return memberInState == strippedIamMember
		}

		if memberInState := d.Get("domain").(string); memberInState != "" {
			return memberInState == strippedIamMember
		}

		if memberInState := d.Get("special_group").(string); memberInState != "" {
			return memberInState == strippedIamMember
		}
	}

	return false
}

// this function will go through a response's access list and see if the iam_member has been reassigned to a different member_type
// if it has, it will return the member type, and the member
func resourceBigQueryDatasetAccessReassignIamMemberInNestedObjectList(d *schema.ResourceData, meta interface{}, items []interface{}) (member_type string, member interface{}, err error) {
	expectedRole, err := expandNestedBigQueryDatasetAccessRole(d.Get("role"), d, meta.(*Config))
	if err != nil {
		return "", nil, err
	}
	expectedFlattenedRole := flattenNestedBigQueryDatasetAccessRole(expectedRole, d, meta.(*Config))

	expectedIamMember, err := expandNestedBigQueryDatasetAccessIamMember(d.Get("iam_member"), d, meta.(*Config))
	if err != nil {
		return "", nil, err
	}
	expectedFlattenedIamMember := flattenNestedBigQueryDatasetAccessIamMember(expectedIamMember, d, meta.(*Config))

	parts := strings.SplitAfter(expectedFlattenedIamMember.(string), ":")

	expectedStrippedIamMember := parts[0]
	if len(parts) > 1 {
		expectedStrippedIamMember = parts[1]
	}

	// Search list for this resource.
	for _, itemRaw := range items {
		if itemRaw == nil {
			continue
		}
		item := itemRaw.(map[string]interface{})

		itemRole := flattenNestedBigQueryDatasetAccessRole(item["role"], d, meta.(*Config))
		// isEmptyValue check so that if one is nil and the other is "", that's considered a match
		if !(isEmptyValue(reflect.ValueOf(itemRole)) && isEmptyValue(reflect.ValueOf(expectedFlattenedRole))) && !reflect.DeepEqual(itemRole, expectedFlattenedRole) {
			log.Printf("[DEBUG] Skipping item with role= %#v, looking for %#v)", itemRole, expectedFlattenedRole)
			continue
		}

		itemUserByEmail := flattenNestedBigQueryDatasetAccessUserByEmail(item["userByEmail"], d, meta.(*Config))
		if reflect.DeepEqual(itemUserByEmail, expectedStrippedIamMember) {
			log.Printf("[DEBUG] Iam Member changed to userByEmail= %#v)", itemUserByEmail)
			return "user_by_email", itemUserByEmail, nil
		}
		itemGroupByEmail := flattenNestedBigQueryDatasetAccessGroupByEmail(item["groupByEmail"], d, meta.(*Config))
		if reflect.DeepEqual(itemGroupByEmail, expectedStrippedIamMember) {
			log.Printf("[DEBUG] Iam Member changed to groupByEmail= %#v)", itemGroupByEmail)
			return "group_by_email", itemGroupByEmail, nil
		}
		itemDomain := flattenNestedBigQueryDatasetAccessDomain(item["domain"], d, meta.(*Config))
		if reflect.DeepEqual(itemDomain, expectedStrippedIamMember) {
			log.Printf("[DEBUG] Iam Member changed to domain= %#v)", itemDomain)
			return "domain", itemDomain, nil
		}
		itemSpecialGroup := flattenNestedBigQueryDatasetAccessSpecialGroup(item["specialGroup"], d, meta.(*Config))
		if reflect.DeepEqual(itemSpecialGroup, expectedStrippedIamMember) {
			log.Printf("[DEBUG] Iam Member changed to specialGroup= %#v)", itemSpecialGroup)
			return "special_group", itemSpecialGroup, nil
		}
		itemIamMember := flattenNestedBigQueryDatasetAccessIamMember(item["iamMember"], d, meta.(*Config))
		if reflect.DeepEqual(itemIamMember, expectedFlattenedIamMember) {
			log.Printf("[DEBUG] Iam Member stayed as iamMember= %#v)", itemIamMember)
			return "", nil, nil
		}
		continue
	}
	log.Printf("[DEBUG] Did not find item for resource %q)", d.Id())
	return "", nil, nil
}